// PARADIME INTERPRETER
//
//LICENSED FREELY UNDER MIT.
//CREATED FOR FREE USE.
#include "StdAfx.h"	
#include "core/Interpreter.h"
#include "core/variant.h"
#include "globalresource.h"
#include "core/errorcodes.h"

// Global data
HINSTANCE				AppInstance;			// Main application instance
HWND					MainWinHnd;				// Main window handle
LPSTR*					CmdLine;
MSG						WinNextMsg;
char					PROCESS_INTENT = INTENT_SCRIPT_INTERPRETER; //see the .h file for details.






///////////////////////////////////////////////////////
//This function is called from Paradime.cpp when it is time to fire up everything
//and make Paradime do its job.
///////////////////////////////////////////////////////
void Global_ParseCmdLineandSTART(void){
	char filename[MAX_PATH+1];
	char* commandline = *CmdLine;
	int pos = 0;
	int writepos = 0;
	int QuoteMode = 0;
	char letter;



	//The intention of this EXE is to execute a script.
	if(PROCESS_INTENT == INTENT_SCRIPT_INTERPRETER){

		if(strlen(commandline)<4)//Make sure something was actually passed.
			Global_ErrorDie(GLOBAL_INVALID_CMDLINE, "Unable to execute script:\n\nInvalid (or no) scriptpath passed in command line.");
		
		// Skip leading spaces
		while ( (letter = commandline[pos]) == ' ' || letter  == '\t')
			pos++;

		//The path must be enclosed in " or '.
		if(((letter = commandline[pos]) != '"') && (letter != '\''))
			Global_ErrorDie(GLOBAL_INVALID_CMDLINE, "Error Parsing Command line: Expected \" or '\n\nExample: \"C:\\MyScript.au3");
	
		pos++;
		while(((letter = commandline[pos]) != '"') && (letter != '\'')){
			filename[writepos] = letter;
			pos++;writepos++;
		}
		filename[writepos] = '\0';
		//We have the script filename, lets execute.
		ScriptExec_Startup( filename);
	}



}




///////////////////////////////////////////////////////
//Initalises the critical shared conponents of Paradime.
///////////////////////////////////////////////////////
void Global_ResourcesInit(void){
	RegisterStandardClass();
}




///////////////////////////////////////////////////////
//This function is called when a script needs to be executed,
//and is called with the filename of the script to execute.
//FIXME: Currently does NOT fork/thread off. Will need to in future.
///////////////////////////////////////////////////////
int ScriptExec_Startup(char* filepath){
	//Instantiate the Root interpreter, and load the code.
	Interpreter Interpreter("Root", 0);
	//Loadup the code
	if(!Interpreter.Set_Raw_CodeFILE(filepath)){
		std::cout << "Error Loading Code!";
		ExitProcess(1);
	}
	Interpreter.Start();

	//MessageBoxA(NULL, "NOTICE:\n\nEnd of code execution.", "Paradime DEBUG", 0x10) ;
	return 1;
}




/////////////////////////////////////////////////////////////////////////////
//Outputs an error message, then gracefully shuts down everything and dies.
/////////////////////////////////////////////////////////////////////////////
void Global_ErrorDie(int errorcode, char* message){
		char titlebuf[250];
		char errorbuf[10];
		itoa( errorcode, (char*)&errorbuf, 10);

		strcpy(titlebuf, ERRORMSG_TITLE);
		strcat(titlebuf, ": ");
		strcat(titlebuf, errorbuf);
		MessageBoxA(NULL, message, titlebuf , 0x10) ;
		ExitProcess(-1);
}


/////////////////////////////////////////////////////////////////////////////
//			GUI CODE
/////////////////////////////////////////////////////////////////////////////


//Standard Definition for windows.
void RegisterStandardClass(void){

	WNDCLASSEX	wndClass;
	HBRUSH		hBrush	= GetSysColorBrush(COLOR_BTNFACE);
	HCURSOR		hCursor = LoadCursor(NULL, IDC_ARROW);

	// Init the class structure for the main class
	wndClass.cbSize			= sizeof(wndClass);
	wndClass.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wndClass.cbClsExtra		= 0;
	wndClass.cbWndExtra		= 0;
	wndClass.hInstance		= AppInstance;
	wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground	= hBrush;
	wndClass.lpszMenuName	= NULL;
	wndClass.lpszClassName	= "PARADIMEAPPDEFAULT";
	wndClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wndClass.hIconSm		= LoadIcon(NULL, IDI_APPLICATION);
	wndClass.lpfnWndProc	= WndProc;

	RegisterClassEx(&wndClass);

}



/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//			WINDOWS MESSAGE HANDLING CODE
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////



//Callback when a message is fired.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_CLOSE:
			DestroyWindow(hwnd);
		break;
		case WM_DESTROY:
			PostQuitMessage(0);
		break;
		default:
			return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}


//This continues to loop till the system shuts down.
int Global_DoWinMsgLoop(void){

	while(GetMessage(&WinNextMsg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&WinNextMsg);
		DispatchMessage(&WinNextMsg);
	}
	return WinNextMsg.wParam;

}